/*
 * @(#)WriteTag.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework.taglib.bean;

import java.util.Hashtable;

import javax.servlet.jsp.JspException;

import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.ResponseUtils;

import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.UserInfoFactory;
import com.dcivision.framework.Utility;

/**
  WriteTag.java

  <p>This class is to extend the WriteTag provided by Apache Struts.<p>
  <p>Modification in "struts-bean.tld"<br>
  <pre>
     [FROM]
     &lt;tagclass&gt;org.apache.struts.taglib.bean.WriteTag&lt;/tagclass&gt;
     [TO]
     &lt;tagclass&gt;com.dcivision.framework.taglib.bean.WriteTag&lt;/tagclass&gt;

     [ADDED]
     &lt;attribute&gt;
     &lt;name&gt;replace&lt;/name&gt;
     &lt;required&gt;false&lt;/required&gt;
     &lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;
     &lt;/attribute&gt;
     &lt;attribute&gt;
     &lt;name&gt;escape&lt;/name&gt;
     &lt;required&gt;false&lt;/required&gt;
     &lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;
     &lt;/attribute&gt;
  </pre>
  </p>

    @author          Rollo Chan
    @company         DCIVision Limited
    @creation date   04/07/2003
    @version         $Revision: 1.11 $
*/

public class WriteTag extends org.apache.struts.taglib.bean.WriteTag {

  public static final String REVISION = "$Revision: 1.11 $";

  private String replace = GlobalConstant.EMPTY_FIELD;

  protected static Hashtable javascriptEscapes;
  protected boolean ignore = true;
  protected boolean escape = false;

  static {
    javascriptEscapes = new Hashtable();
    javascriptEscapes.put("\\", "\\\\");
    javascriptEscapes.put("\t", "\\t");
    javascriptEscapes.put("\f", "\\f");
    javascriptEscapes.put("\n", "\\n");
    javascriptEscapes.put("\r", "\\r");
    javascriptEscapes.put("'", "\\'");
    javascriptEscapes.put("\"", "\\\"");
  }

  /**
   * Process the start tag.
   *
   * @exception JspException if a JSP exception has occurred
   */
  public int doStartTag() throws JspException {        
    // Look up the requested bean (if necessary)
    if (ignore) {
      if (RequestUtils.lookup(pageContext, name, scope)==null){
        if (filter) {
          ResponseUtils.write(pageContext, ResponseUtils.filter(replace));
        } else {
          ResponseUtils.write(pageContext, replace);
        }
        return (SKIP_BODY);  // Nothing to output
      }
    }
    // Look up the requested property value
    Object value = RequestUtils.lookup(pageContext, name, property, scope);
    if (value==null){
      if (filter) {
        ResponseUtils.write(pageContext, ResponseUtils.filter(replace));
      } else {
        ResponseUtils.write(pageContext, replace);
      }
      return(SKIP_BODY);  // Nothing to output
    }

    // Convert value to the String with some formatting
    String output = formatValue(value);

    // Print this property value to our output writer, suitably filtered and add email link if applicable
    if (escape) {
      output = searchReplace(output, javascriptEscapes);
    }

    if (filter) {
      output = ResponseUtils.filter(output);
    }

    if ( "creatorName".equals(property) ) {
      Integer id = (Integer)RequestUtils.lookup(pageContext, name, "creatorID", scope);
      output = addEmailLinkByID(output, id);
    }
    if ( "updaterName".equals(property) ) {
      Integer id = (Integer)RequestUtils.lookup(pageContext, name, "updaterID", scope);
      output = addEmailLinkByID(output, id);
    }

    ResponseUtils.write(pageContext, output);

    // Continue processing this page
    return(SKIP_BODY);  // Nothing to output
  }

  /**
   * Format value according to specified format string (as tag attribute or
   * as string from message resources) or to current user locale.
   * replace with "replace" attribute if the bean is empty or null
   *
   * @param valueToFormat value to process and convert to String
   * @exception JspException if a JSP exception has occurred
   */
  protected String formatValue(Object valueToFormat) throws JspException {
    if (valueToFormat instanceof java.util.Date && formatStr != null) {
      java.util.Locale locale = RequestUtils.retrieveUserLocale(pageContext, this.localeKey);
      return new java.text.SimpleDateFormat(formatStr, locale).format(valueToFormat);
    }    
    
    String formattedValue = super.formatValue(valueToFormat);
    if (formattedValue==null || formattedValue.length()==0) {
      formattedValue = replace;
    }

    return formattedValue;
  }

  /** Setter to set the replacement val when the bean is empty*/
  public void setReplace(String val) {
    replace = val;
  }

  public void setEscape(boolean val) {
    this.escape = val;
  }

  protected static String searchReplace(String in, Hashtable pairs) {
    StringBuffer out = new StringBuffer(in.length() * 2);
    String r = null;
    int len = in.length();
    for(int i = 0; i<len; i++) {
      String c = in.substring(i, i + 1);
      r = (String)pairs.get(c);
      if (r!=null) {
        out.append(r);
      } else {
        out.append(c);
      }
    }

    return out.toString();
  }

  /**
   * add a hyperlink to the email of the user with the given id,
   * do nothing if email not exist
   *
   * @param      output   the string on which the hyperlink is added
   * @param      id       the id of the user having the email
   * @return     hyperlink added on output
   */
  private String addEmailLinkByID(String output, Integer id) {
    String email = UserInfoFactory.getUserEmailAddress(id);
    output = "<nobr>" + output + "</nobr>";
    if ( !Utility.isEmpty(email) ) {
      return "<a href='mailto:" + email + "'>" + output + "</a>";
    } else {
      return output;
    }
  }

  public void release() {
    super.release();
    replace = null;
    ignore = true;
    escape = false;
  }
  

  
}
